<html>
<head><meta charset="utf-8"><title>Should pure imply nomem · project-inline-asm · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/index.html">project-inline-asm</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html">Should pure imply nomem</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="189440087"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189440087" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189440087">(Mar 01 2020 at 17:10)</a>:</h4>
<p>I noticed that LLVM will only optimize away an <code>asm</code> with unused outputs if both the <code>pure</code> and <code>nomem</code> flags are set.</p>



<a name="189440102"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189440102" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189440102">(Mar 01 2020 at 17:11)</a>:</h4>
<p>Based on our current rules for <code>pure</code>, code using it can't read or write memory anyways.</p>



<a name="189440148"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189440148" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189440148">(Mar 01 2020 at 17:12)</a>:</h4>
<p>I can see 2 options:<br>
a) <code>pure</code> implies <code>nomem</code> and it is an error to specify both.<br>
b) <code>pure</code> requires the <code>nomem</code> flag to also be set. It is an error otherwise.</p>



<a name="189440359"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189440359" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189440359">(Mar 01 2020 at 17:18)</a>:</h4>
<p>Oh wait actually it's even worse. LLVM will happily remove a <code>nomem</code> or <code>readonly</code> asm, even if it is marked as <code>sideeffect</code>.</p>



<a name="189441097"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441097" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441097">(Mar 01 2020 at 17:43)</a>:</h4>
<p>OK, let's consider the cases we need to model:</p>
<ul>
<li>Pure function which doesn't access memory. No side effects, outputs depend only on inputs.</li>
<li>Doesn't access memory, but may have side effects (e.g. modifying a control register)</li>
<li>Pure-ish function which only reads memory. No side effects, outputs depend on inputs + memory.</li>
<li>Arbitrary memory reads/write &amp; side effects.</li>
</ul>



<a name="189441150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441150">(Mar 01 2020 at 17:44)</a>:</h4>
<p>I would argue that <code>sideeffect</code> and <code>nomem</code> being specified at the same time is a bug, as those are mutually exclusive in LLVM AFAIK.</p>



<a name="189441153"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441153" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441153">(Mar 01 2020 at 17:44)</a>:</h4>
<p>And here are the LLVM attributes we have to work with: readnone, readonly, writeonly, argmemonly, inaccessiblememonly, inaccessiblemem_or_argmemonly</p>



<a name="189441167"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441167" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441167">(Mar 01 2020 at 17:45)</a>:</h4>
<p><span class="user-mention" data-user-id="123586">@nagisa</span> Actually <code>sideeffect</code> is an attribute on the asm, while <code>readnone</code> is an attribute on the <code>call</code> instruction that invokes the asm. So they don't actually interact in LLVM.</p>



<a name="189441168"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441168" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441168">(Mar 01 2020 at 17:45)</a>:</h4>
<p><code>readonly sideeffect</code> being optimised out sounds like a bug.</p>



<a name="189441232"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441232" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441232">(Mar 01 2020 at 17:46)</a>:</h4>
<p><code>sideeffect</code> is only actually looked at deep in the backend. By then the <code>call asm</code> has already been optimized away.</p>



<a name="189441290"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441290" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441290">(Mar 01 2020 at 17:48)</a>:</h4>
<p>I didn’t look much at the <code>asm</code>'s sideeffect annotation, but the <code>sideeffect</code> intrinsic does interact with the <code>readnone</code> etc attributes very much. In particular <code>sideeffect</code> prevents LLVM from inferring a <code>readnone</code> attribute where it otherwise would. But if <code>readnone</code> is already specified somewhere, that takes precedence.</p>



<a name="189441296"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441296" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441296">(Mar 01 2020 at 17:48)</a>:</h4>
<p>And <code>readnone</code> is exactly what makes LLVM to delete things it considers to be dead code.</p>



<a name="189441307"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441307" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441307">(Mar 01 2020 at 17:49)</a>:</h4>
<p>(this most likely applies to <code>readonly</code> the same way)</p>



<a name="189441311"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441311" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441311">(Mar 01 2020 at 17:49)</a>:</h4>
<p>I think we should use <code>inaccessiblememonly</code> instead of <code>readnone</code> for non-pure asm with <code>nomem</code>. That tells LLVM that the asm doesn't touch any LLVM-visible memory, but still has some significant side-effect.</p>



<a name="189441416"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441416" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441416">(Mar 01 2020 at 17:52)</a>:</h4>
<p>I wouldn't add <code>readnone</code> attribute at all and let LLVM infer it. <code>inaccessiblememonly</code> or <code>inaccessiblemem_or_argmemonly</code> sound like saner choices.</p>



<a name="189441426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441426">(Mar 01 2020 at 17:53)</a>:</h4>
<p>LLVM can't infer it because it can't read the asm.</p>



<a name="189441439"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441439" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441439">(Mar 01 2020 at 17:53)</a>:</h4>
<p>Clang uses <code>readnone</code>/<code>readonly</code> only for non-volatile asm.</p>



<a name="189441485"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441485" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441485">(Mar 01 2020 at 17:54)</a>:</h4>
<p>Well… I guess. I don’t remember the RFC well enough to contribute to the discussion much here.</p>



<a name="189441891"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189441891" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189441891">(Mar 01 2020 at 18:05)</a>:</h4>
<p>Hmm I think I'm going to go with option b: <code>pure</code> must be used with either <code>nomem</code> or <code>readonly</code>, otherwise error. And I will relax the rules of <code>pure</code> to allow reading from memory when used with <code>readonly</code>.</p>



<a name="189442000"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189442000" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189442000">(Mar 01 2020 at 18:08)</a>:</h4>
<p>So that leaves 4 valid combinations:</p>
<ul>
<li><code>pure</code> <code>nomem</code></li>
<li><code>pure</code> <code>readonly</code></li>
<li><code>nomem</code></li>
<li><code>readonly</code></li>
</ul>



<a name="189442021"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189442021" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189442021">(Mar 01 2020 at 18:09)</a>:</h4>
<p>Which lower to:</p>
<ul>
<li><code>readnone</code></li>
<li><code>readonly</code></li>
<li><code>inaccessiblememonly</code></li>
<li>(nothing)</li>
</ul>



<a name="189442715"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189442715" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189442715">(Mar 01 2020 at 18:28)</a>:</h4>
<p>what do writes count as? the "nothing" category?</p>



<a name="189442790"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189442790" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189442790">(Mar 01 2020 at 18:30)</a>:</h4>
<p><span class="user-mention silent" data-user-id="224471">Lokathor</span> <a href="#narrow/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem/near/189442715" title="#narrow/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem/near/189442715">said</a>:</p>
<blockquote>
<p>what do writes count as? the "nothing" category?</p>
</blockquote>
<p>I believe the default plain <code>asm!</code> without annotations is the conservative thing and will allow arbitrary things (including writes)</p>



<a name="189442876"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189442876" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189442876">(Mar 01 2020 at 18:33)</a>:</h4>
<p>Sorry 5 combinations, the last one being no attributes, which also corresponds to (nothing)</p>



<a name="189442886"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/216763-project-inline-asm/topic/Should%20pure%20imply%20nomem/near/189442886" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/216763-project-inline-asm/topic/Should.20pure.20imply.20nomem.html#189442886">(Mar 01 2020 at 18:33)</a>:</h4>
<p>LLVM doesn't have any attributes to represent <code>inaccessiblemem_or_readonly</code>, so we have to be conservative for <code>readonly</code> without <code>pure</code>.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>